<template>
  <BaseContainer>
    <a-form
      ref="FormRef"
      layout="inline"
      :model="formFields"
      :rules="formRules"
      label-align="left"
      hideRequiredMark
      class="form"
    >
      <a-form-item label="类型" class="form-item">
        <a-radio-group v-model:value="showType" button-style="solid" @change="loadDashboard" class="mr-3">
          <a-radio-button :value="ShowTypeEnum.List">表格</a-radio-button>
          <a-radio-button :value="ShowTypeEnum.Line">折线图</a-radio-button>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="端口" class="form-item">
        <a-select
          :options="platformOptions"
          class="w-130"
          placeholder="请选择端口"
          v-model:value="formFields.clientType"
        />
      </a-form-item>
      <a-form-item name="keyword" label="关键词" class="order-keyword form-item">
        <a-select
          v-model:value="formFields.keyword"
          show-search
          class="w-130"
          placeholder="请搜索关键词"
          :default-active-first-option="false"
          :filter-option="false"
          allow-clear
          :loading="keywordLoading"
          :not-found-content="keywordLoading ? undefined : '暂无数据'"
          :options="keywords"
          @search="handleSearchKeyword"
        >
          <template v-if="keywordLoading" #notFoundContent> <a-spin size="small" />查询中 </template>
        </a-select>
      </a-form-item>
      <a-form-item label="时间范围" name="startTime" class="form-item">
        <a-range-picker class="mr-2" v-model:value="dateRange" value-format="YYYY-MM-DD HH:mm:ss" />
        <a-button @click="handleSearch" type="primary" :loading="loading || lineLoading">搜索</a-button>
      </a-form-item>
    </a-form>
    <Divider class="line" />
    <div class="chart" v-if="showType === ShowTypeEnum.Line">
      <vue-echarts :loading-options="loadingOptions" :loading="lineLoading" :option="option" width="100%" autoresize />
    </div>
    <a-table
      v-else
      :data-source="monitorList.monitorWords"
      :pagination="pagination"
      :loading="loading"
      :columns="columns"
      @change="handleTableChange"
    />
  </BaseContainer>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref } from 'vue'
import VueEcharts from 'vue-echarts'
import { use } from 'echarts/core'
import { LineChart } from 'echarts/charts'
import { SVGRenderer } from 'echarts/renderers'
import { GraphicComponent, GridComponent, LegendComponent, TitleComponent, TooltipComponent } from 'echarts/components'
import BaseContainer from '@/components/base-container/index.vue'
import Divider from '@/components/divider/index.vue'
import dayjs, { Dayjs } from 'dayjs'
import { debounce } from 'lodash-es'
import { DateRangeEnum, ShowTypeEnum } from '@/views/dashboard/interface'
import { formatDate, toLabelValue } from '@/utils'
import { FormInstance, message, TableProps } from 'ant-design-vue'
import { PlatformEnum } from '@/core/enums/platform'
import getMonitorKeywords from '@/services/monitor/getMonitorKeywords'
import getMonitorChart from '@/services/monitor/getMonitorChart'
import getMonitorList from '@/services/monitor/getMonitorList'

interface MonitorFields {
  keyword?: string
  startTime?: Dayjs
  endTime?: Dayjs
  clientType: PlatformEnum
}

const PlatformKeyMap: Record<PlatformEnum, string> = {
  [PlatformEnum.PC]: 'PC端',
  [PlatformEnum.MOBILE]: '移动端',
  [PlatformEnum.Platform]: '全部'
}

const FormRef = ref<FormInstance>()
const platformOptions = ref(toLabelValue(PlatformKeyMap))
const showType = ref<ShowTypeEnum>(ShowTypeEnum.List)
const formFields = reactive<MonitorFields>({
  keyword: undefined,
  startTime: undefined,
  endTime: undefined,
  clientType: PlatformEnum.Platform
})

const formRules = reactive({
  startTime: [
    {
      required: true,
      trigger: 'change',
      message: '请选择时间范围'
    }
  ]
})

const pagination = reactive({
  current: 1,
  pageSize: 50,
  total: 0
})

const columns: TableProps['columns'] = [
  {
    title: '关键词',
    dataIndex: 'name',
    key: 'name'
  },
  {
    title: '流量接口热度',
    dataIndex: 'flowHeatRate',
    key: 'flowHeatRate'
  },
  {
    title: '推荐词接口热度',
    dataIndex: 'recommendHeatRate',
    key: 'recommendHeatRate'
  },
  {
    title: '端口',
    dataIndex: 'clientType',
    key: 'clientType',
    customRender: ({ text }: { text: PlatformEnum }) => PlatformKeyMap[text]
  },
  {
    title: '时间',
    dataIndex: 'createTime',
    key: 'createTime'
  }
]

const dateRange = computed({
  get() {
    if (formFields.startTime && formFields.endTime) {
      return [formFields.startTime, formFields.endTime]
    } else {
      return []
    }
  },
  set(val?: Dayjs[]) {
    if (val) {
      formFields.startTime = val[0]
      formFields.endTime = val[1]
    } else {
      formFields.startTime = undefined
      formFields.endTime = undefined
    }
  }
})

const [monitorList, fetchMonitorList, loading] = getMonitorList()
const [monitorLine, fetchMonitorLine, lineLoading] = getMonitorChart()
const [keywords, fetchMonitorKeyword, keywordLoading] = getMonitorKeywords()
use([LineChart, SVGRenderer, GridComponent, GraphicComponent, LegendComponent, TooltipComponent, TitleComponent])

const loadingOptions = reactive({
  text: '加载中...'
})
const option = computed(() => {
  return {
    grid: {
      left: '0%',
      right: '0%',
      bottom: '0%',
      containLabel: true
    },
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: ['流量接口', '推荐词接口']
    },
    graphic: {
      type: 'text', // 类型：文本
      left: 'center',
      top: 'middle',
      silent: true, // 不响应事件
      invisible: lineLoading.value || Object.keys(monitorLine.value).length > 0, // 有数据就隐藏
      style: {
        fill: '#9d9d9d',
        fontWeight: 'bold',
        text: '暂无数据',
        fontFamily: 'Microsoft YaHei',
        fontSize: '25px'
      }
    },
    xAxis: {
      data: Object.keys(monitorLine.value.flowHeat),
      axisLine: {
        show: true,
        lineStyle: {
          color: '#D1D3D6'
        }
      },
      axisLabel: {
        color: '#777d89'
      },
      axisTick: {
        show: false
      }
    },
    yAxis: {
      axisLabel: {
        show: true,
        color: '#777d89'
      }
    },
    series: [
      {
        name: '流量接口',
        type: 'line',
        label: {
          show: true,
          position: 'top'
        },
        smooth: true,
        data: Object.values(monitorLine.value.flowHeat)
      },
      {
        name: '推荐词接口',
        type: 'line',
        label: {
          show: true,
          position: 'top'
        },
        smooth: true,
        data: Object.values(monitorLine.value.recommendHeat)
      }
    ]
  }
})

function handleDateSelect() {
  const month = dayjs().subtract(1, 'month')
  dateRange.value = [month, dayjs()]
}

const handleSearchKeyword = debounce((keyword: string) => {
  if (keyword) {
    fetchMonitorKeyword({
      keyword
    })
  }
}, 500)

function loadDashboard() {
  FormRef.value?.validate().then(async () => {
    const params = {
      ...formFields,
      keyword: formFields.keyword || '',
      startTime: formatDate(formFields.startTime!),
      endTime: formatDate(formFields.endTime!),
      pageSize: pagination.pageSize,
      pageNum: pagination.current
    }

    if (showType.value === ShowTypeEnum.List) {
      const [err, res] = await fetchMonitorList(params)

      if (err) {
        message.error(err.message)
      } else {
        pagination.total = res.data.data?.totalSize ?? 0
      }
    } else {
      const [err] = await fetchMonitorLine(params)

      if (err) {
        message.error(err.message)
      }
    }
  })
}

function handleTableChange(pag: { pageSize: number; current: number }) {
  pagination.pageSize = pag.pageSize
  pagination.current = pag.current
  loadDashboard()
}

function handleSearch() {
  FormRef.value?.validate().then(() => {
    loadDashboard()
  })
}

onMounted(() => {
  handleDateSelect()
})
</script>

<script lang="ts">
export default {
  name: 'monitor'
}
</script>

<style lang="scss" scoped>
.w-130 {
  width: 130px;
}

.order-keyword {
  &__search {
    max-width: 200px;
  }
}

.line {
  margin-top: 0;
}

.chart {
  width: 100%;
  height: 400px;
}

.form-item {
  height: 54px;
  margin-bottom: 0;
}
</style>
